闲话 22.8.13

闲话

好的今天来一些Ayase的歌!是Fiction Blue!
说到ayase,我觉得更多人应该熟悉他和ikura的组合yoasobi
但比起真人我还是更喜欢miku
哇说实在的这首歌的曲部分实在是太好听了
他是怎么写出这种曲的

Fiction Blue

あの日の景色にまた漕ぎ出せば
若是再次乘舟向着那天的景色驶去
揺れ色重ね発つ日に浮かべた
于启程之日所见的层层摇曳色彩便浮现出来
夏の音に引かれて振り返る度
每当被夏日的旋律吸引而回头之时
あの日の君が笑う
看到的便是在那一天微笑着的你

言葉を奪う程の陽射しと
让人哑然的炽热阳光
恥ずかしい程青すぎる空
让人羞愧的蔚蓝天空
眩暈がしそうな程渇いた空気の匂い
让人快要晕倒般干燥空气的气息
待ち合わせはいつものあの場所で
相约在那个老地方碰头
捻れた景色を切り裂く様に
仿佛要撕裂这扭曲的景色一般
無邪気な瞳で強く僕の手を引いた
眼里满是天真的你紧紧的牵起了我的手
誰も居ないとこまで二人で行こうかなんて
说着 一起去只有我们两个人的地方吧
笑い合ってた
相视而笑

あの日から動かない時が今
从那一天开始停滞的时间
脈打つ度に瞼に流れる
如今每次脉搏跳动都会在眼前流淌
狂おしい程にただ輝いていた
如同发狂一般仅仅只是闪耀着
あの日の二人が笑う
那一天的我们曾展露笑颜

誰に願わずとも
就算没有向谁许愿
悪戯に流れる時の中で
身高也在像是恶作剧般流转的时间之中
いつしか伸びた背丈
不知何时悄然增长
似合わない僕を
看着这个不相配的我
どうか笑ってくれないか
就请你笑一笑吧
君が笑えば釣られて笑った
看到你的笑容我也跟着笑了起来
懐かしい景色この指にそっと
手指轻触这怀念的景色
掠めて消えたあの二人の声は
嘶哑而终究消失的两个人的声音
今もそこにあるのかな
如今还残留在那里吗

捻れた景色を切り裂く様に
仿佛要撕裂这扭曲的景色一般
無邪気な瞳で強く夏の手を引いた
眼里满是天真的你紧紧地牵起了夏天的手
誰も知らないあの場所で待ち合わせようよ
在谁也不知道的那个地方碰头吧
だからまたね
所以说 再见了

あの日の景色に取り残された
我被留在了那一天的景色之中
君の手を引くその時聞こえた
但是牵起你的手的时候所听到的
懐かしい声にただ
这怀念的声音
ただ泣いている
只是潸然泪下
あの日の僕の様に
就像那一天的我一样

あの日から動かない時が今
从那一天开始停滞的时间
ほんの少しだけ進んで見えた
如今却能稍微看到前进了
やがて廻る季節よ輝いていて
终于开始流转的季节啊 请你绽放光彩
二人が笑えるように
让我们可以绽放笑颜

どれだけ時間が過ぎたとしても
不管度过多少时光
どれだけ季節の色数えても
数过多少次四季的色彩
あの日二人並んで見下ろした景色
那一天两人在一起俯瞰到的景色
忘れることはないから
永远不会忘记
君と手を繋いだ夏の日よ
与你手牵手度过的夏日啊

最近应该会放一些杂歌 但大概都是术力口(
正好我在《其人》里写到我喜欢一部分术曲
也可以从最近的这些推歌里稍微看到一部分我的喜好

?闲话的阅读量少了

一道树形dp题

一棵有根树对于常数 \(\alpha\) 平衡性的定义是:

  1. 它的所有子树是平衡的。
  2. 当它有 \(2\) 个及以上的子节点的时候,记这棵树的大小为 \(S\),则它任意子树的大小 $ S' $ 应满足 \(S' \le \alpha S\)

给出一棵 \(n\) 个节点的树。有 \(T\) 组询问,每组询问以两个整数 \(a,b\) 的方式给出 \(\alpha = \frac a b\),保证 \(0 \le a \le b\)。你需要求出有多少个节点为根能让整棵树对于 \(\alpha\) 平衡。询问强制在线。

\(n \le 10^5, T \le 10^5\)

定义一个对象的 \(\alpha\) 阈值为特定的 \(\alpha_0\),对象对 \(> \alpha_0\) 的任意数均不平衡。

我们发现答案具有单调性。只要预处理每个点的 \(\alpha\) 阈值,排序后对于每个询问二分答案即可。
考虑如何通过dp求得。

首先考虑 \(O(n)\) 求出单点的 \(\alpha\) 阈值。
这是很简单的,依题意模拟即可。我们只需要进行一次dfs,得到每个节点最大子树大小 \(\text{maxsize}\) 与 子树大小 \(\text{totsize}\),并在过程中取节点 \(\alpha\) 阈值为子树中 \(\alpha\) 阈值的最大值。递归返回时,若该节点子树数量 \(>1\),则取 \(\alpha\) 阈值为原阈值和 $ \frac {\text{maxsize}} {\text{totsize}}$ 中的最大值。
由于每次复杂度 \(O(n)\),因此我们有了 \(O(n^2)\) 的预处理。

然而这是不够的。
在朴素思路中,我们一直在关注根节点被别人更新的情况,但换种思路——关注一个节点被更新的情况。我们发现,朴素方式dfs时,一条边只会被以一个方向经过一次。关注这种情况与更新间的联系,即,我们将一条无向边 \((u,v)\) 拆成两条方向相反的有向边,讨论其中一条边对更新造成的影响。
定义一条有向边 \(u \rightarrow v\)\(\alpha\) 平衡,当且仅当 \(u\) 作为根节点时其子树数量 \(\le 2\),或是 \(\frac {\text{v 为根时除 u 所属子树外最大子树大小}} {\text{u为根时 v 子树大小}} \le \alpha\)。根据定义,一条边的 \(\alpha\) 阈值即为后半部分的比值。
来解释一下这样定义的必要性。我们考虑当以一个节点 \(\text{root}\) 为根时对整棵树进行dfs时经过了 \(u \rightarrow v\),此时若想使得 \(\text{root}\)\(\alpha\) 平衡,则需要有 \(u \rightarrow v\)\(\alpha\) 平衡,而且当所有dfs树上的 \(u \rightarrow v\) 均对 \(\alpha\) 平衡(且 \(\text{root}\) 的最大子树 \(\le \alpha n\))时有 \(\text{root}\)\(\alpha\) 平衡。因此有充要,该定义是良的。
在得到任意有向边的 \(\alpha\) 阈值后,我们就可以更新有向边所能更新点的 \(\alpha\) 阈值得到最终答案了。
一条边 \(u \rightarrow v\) 所能更新的点集为\(\{p | p 为以 v 为根 u 子树上的节点\}\)。当且仅当一个节点属于 \(u \rightarrow v\) 的点集时,该节点的 \(\alpha\) 阈值为其原 \(\alpha\) 阈值与该边的 \(\alpha\) 阈值之间的最大值。
我们发现一条边所能更新的点在dfn序上连续。因此,只需要跑出dfn序,我们就可以通过区间取max的方式得到每个dfn序对应节点的 \(\alpha\) 阈值。
讨论如何遍历边。我们可以考虑对于每个节点,以该节点为 \(v\),与其连接的点为 \(u\) 讨论 \(u \rightarrow v\) 的贡献。这是很容易的。保存每个点为根时子树的最大值和次大值,依定义更新即可。注意当 \(u\) 在以1为根的子树上为 \(v\) 的父亲时的情况,此时需要特殊判定。最后对于每个节点更新以自己为根时的情况,即 $ \frac {\text{maxsize}} {\text{totsize}}$ 即可。

代码
#define Aster(s) for ( register int i = head[s]; i; i = e[i].next )
#define v e[i].to
int head[N], mlc;
struct ep {
    int to, next;
} e[N<<1];
inline void adde(int f, int t) {
    e[++mlc].to = t;
    e[mlc].next = head[f];
    head[f] = mlc;
}

struct SegmentBeats {
    double mx, mn, lazy;
    #define ls (p<<1)
    #define rs (p<<1|1)
    #define mx(p) seg[p].mx
    #define mn(p) seg[p].mn
    #define lazy(p) seg[p].lazy
    #define mid ( (l + r) >> 1 )
} seg[N<<2];

void ps_d(int p) {
    if (lazy(p) == 0) return;
    mx(ls) = mn(ls) = lazy(p);
    mx(rs) = mn(rs) = lazy(p);
    lazy(ls) = lazy(rs) = lazy(p);
    lazy(p) = 0;
}

void ps_p(int p) {
    mx(p) = max(mx(ls), mx(rs));
    mn(p) = min(mn(ls), mn(rs));
}

void upd(int p, int l, int r, int L, int R, double val) {
    if (L <= l and r <= R and mx(p) <= val) {
        mx(p) = mn(p) = lazy(p) = val;
        return;
    } ps_d(p);
    if (L <= mid and mn(ls) < val) upd(ls, l, mid, L, R, val);
    if (R > mid and mn(rs) < val) upd(rs, mid+1, r, L, R, val);
    ps_p(p);
}

double ans[N];
void qry(int p, int l, int r) {
    if (l == r) { ans[l] = mx(p); return ; }
    ps_d(p);
    qry(ls, l, mid);
    qry(rs, mid+1, r);
}

int tmstp, dfn[N], siz[N], mx[N], deg[N], lastans;
double alp, maxn;
void dfs(int u, int f) {
    dfn[u] = ++ tmstp; siz[u] = 1; int fir = 0, sec = -1;
    Aster(u) {
        if (v == f) continue;
        dfs(v, u);
        sec = max(sec, siz[v]);
        if (sec > fir) swap(fir, sec);
        siz[u] += siz[v];
    } sec = max(sec, n - siz[u]);
    if (sec > fir) swap(fir, sec);
    Aster(u) {
        if (v == f) {
            maxn = 1.0 * ((n - siz[u]) == fir ? sec : fir) / siz[u];
            if (deg[u] != 2) {
                upd(1, 1, n, 1, dfn[u] - 1, maxn);
                upd(1, 1, n, dfn[u] + siz[u], n, maxn);
            } 
        } else {
            maxn = 1.0 * (siz[v] == fir ? sec : fir) / (n - siz[v]);
            if (deg[u] != 2) {
                upd(1, 1, n, dfn[v], dfn[v] + siz[v] - 1, maxn);
            }
        }
    } if (deg[u] != 1) upd(1, 1, n, dfn[u], dfn[u], 1.0 * fir / n);
}

dfs(1, 0);
qry(1, 1, n);
sort(ans + 1, ans + 1 + n);
rep(i,1,m) {
    get(t1); get(t2);
    t1 ^= (lastans * k), t2 ^= (lastans * k);
    alp = 1.0 * t1 / t2;
    lastans = upper_bound(ans+1, ans+1+n, alp) - ans;
    if(ans[lastans] > alp or lastans == n+1) lastans--;
    printf("%d\n", lastans);
}
posted @ 2022-08-13 20:37  joke3579  阅读(66)  评论(6编辑  收藏  举报